package com.szly.phm.common.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.szly.phm.common.entity.dto.role.CreateRoleDTO;
import com.szly.phm.common.entity.dto.role.RolePageDTO;
import com.szly.phm.common.entity.dto.role.RolePermissionDTO;
import com.szly.phm.common.entity.dto.role.UpdateRoleDTO;
import com.szly.phm.common.entity.dto.user.LoginUserDTO;
import com.szly.phm.common.entity.po.*;
import com.szly.phm.common.entity.result.CodeStatusEnum;
import com.szly.phm.common.entity.result.PageResult;
import com.szly.phm.common.entity.result.RootResponse;
import com.szly.phm.common.entity.vo.login.LoginRoleVO;
import com.szly.phm.common.entity.vo.permissiom.PermissionTreeVO;
import com.szly.phm.common.entity.vo.role.RolePermissionVO;
import com.szly.phm.common.mapper.*;
import com.szly.phm.common.service.ISysRoleService;
import com.szly.phm.common.utils.BeanCopyUtils;
import com.szly.phm.common.utils.HandleUtils;
import com.szly.phm.common.utils.MenuTree;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author admin
 * @since 2021-07-02
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {

    private final SysRolePermissionMapper rolePermissionMapper;

    private final SysUserRoleMapper userRoleMapper;

    private final SysPermissionMapper sysPermissionMapper;

    private final SysOperationMapper sysOperationMapper;

    private final SysRolePermissionMapper  sysRolePermissionMapper;

    private final SysOperationRoleMapper sysOperationRoleMapper;

    private final SysUserMapper sysUserMapper;

    private final SysUserRoleMapper sysUserRoleMapper;
    @Override
    public List<LoginRoleVO> queryRolesByUserId(String userId) {
        var lrs = new ArrayList<LoginRoleVO>();
        var roles = baseMapper.queryRolesByUserId(userId);
        if (HandleUtils.ListIsNotNull(roles)) {
            roles.forEach(m -> {
                var r = new LoginRoleVO();
                BeanCopyUtils.copy(m, r);
                lrs.add(r);
            });
        }
        return lrs;
    }

    @Override
    public RootResponse queryRolePage(RolePageDTO roleDTO) {
        var wrapper = new LambdaQueryWrapper<SysRole>();
        wrapper.eq(SysRole::getIsSoftDelete, false);
        wrapper.ne(SysRole::getRoleName, "超级管理员");
        wrapper.orderByDesc(SysRole::getCreateDateTime);
        if (StringUtils.isNotBlank(roleDTO.getRoleName())) {
            wrapper.like(SysRole::getRoleName, roleDTO.getRoleName());
        }
//        if (StringUtils.isNotBlank(roleDTO.getSystemId())) {
//            wrapper.eq(SysRole::getSystemId, roleDTO.getSystemId());
//        }
//        if (StringUtils.isNotBlank(roleDTO.getRoleType())) {
//            wrapper.eq(SysRole::getRoleType, roleDTO.getRoleType());
//        }
        wrapper.orderByDesc(SysRole::getCreateDateTime, SysRole::getId);
        if ("00".equals(roleDTO.getType())) {
            PageHelper.startPage(roleDTO.getPageNum(), roleDTO.getPageSize());
            var roles = baseMapper.selectList(wrapper);
            var pageInfo = PageInfo.of(roles);
            var pageList = pageInfo.getList();
            return RootResponse.success(PageResult.page(pageList, pageInfo.getPageNum(), pageInfo.getPageSize(), pageInfo.getTotal()));
        } else {
            var roles = baseMapper.selectList(wrapper);
            return RootResponse.success(roles);
        }
    }

    @Override
    public RootResponse createRole(CreateRoleDTO roleDTO, LoginUserDTO userDTO) {
        //检查重名
        if ("999".equals(checkReName(roleDTO.getRoleName()).getCode())) {
            return RootResponse.error( "角色名已存在");
        }
        var role = new SysRole();
        BeanCopyUtils.copy(roleDTO, role);
        role.setId(HandleUtils.UUID32());
        role.setCreateDateTime(new Date());
        role.setCreator(userDTO.getUsername());
        role.setIsSoftDelete(false);
        int i = baseMapper.insert(role);
        if (i != 1) {
            return RootResponse.error();
        }
        return RootResponse.success(role);
    }

    @Override
    public RootResponse updateRole(UpdateRoleDTO roleDTO, LoginUserDTO userDTO) {
        var role = baseMapper.selectById(roleDTO.getId());
        if (role == null || role.getIsSoftDelete()) {
            return RootResponse.error(CodeStatusEnum.NOT_EXIST_DATA);
        }
        //查重名
        if (!roleDTO.getRoleName().equals(role.getRoleName())) {
            if ("999".equals(checkReName(roleDTO.getRoleName()).getCode())) {
                return RootResponse.error("角色名已存在");
            }
        }
        BeanCopyUtils.copy(roleDTO, role);
        role.setUpdateDateTime(new Date());
        role.setUpdater(userDTO.getUsername());
        int i = baseMapper.updateById(role);
        if (i != 1) {
            return RootResponse.error();
        }
        return RootResponse.success(role);
    }

    @Override
    @Transactional
    public RootResponse deleteRole(String roleId, LoginUserDTO userDTO) {
        var queryWrapper = new LambdaQueryWrapper<SysRole>();
        queryWrapper.eq(SysRole::getId, roleId);
        queryWrapper.eq(SysRole::getIsSoftDelete, false);
        var role = baseMapper.selectOne(queryWrapper);
        if (role == null) {
            return RootResponse.error(CodeStatusEnum.NOT_EXIST_DATA);
        }
        role.setUpdater(userDTO.getUsername());
        role.setUpdateDateTime(new Date());
        role.setIsSoftDelete(true);
        int i = baseMapper.updateById(role);
        if (i != 1) {
            return RootResponse.error();
        }
        // 根据角色Id删除角色权限关联关系
        var qWrapper = new LambdaQueryWrapper<SysRolePermission>();
        qWrapper.eq(SysRolePermission::getRoleId, roleId);
        rolePermissionMapper.delete(qWrapper);
        return RootResponse.success(role);
    }

    @Override
    public RootResponse<RolePermissionVO> queryRolePermissions(String roleId) {
        var list = rolePermissionMapper.selectPermissionByRoleId(roleId);
       var operationByRoleIds= sysOperationRoleMapper.selectOperationByRoleId(roleId);
        var rp = new RolePermissionVO();
        rp.setRoleId(roleId);
        var pids = new ArrayList<String>();

        var oIds = new ArrayList<String>();

            list.forEach(n -> {
                pids.add(n.getId());
            });
        operationByRoleIds.forEach(o->{
            oIds.add(o.getId());
                }
        );
            rp.setPermissionIds(pids);
            rp.setOperationIds(oIds);

        return RootResponse.success(rp);
    }



    @Override
    @Transactional
    public RootResponse createAssignPermissions(RolePermissionDTO rolePermissionDTO, LoginUserDTO userDTO) {
        var queryWrapper = new LambdaQueryWrapper<SysRole>();
        queryWrapper.eq(SysRole::getId, rolePermissionDTO.getRoleId());
        queryWrapper.eq(SysRole::getIsSoftDelete, false);
        var role = baseMapper.selectOne(queryWrapper);
        if (role == null) {
            return RootResponse.error(CodeStatusEnum.NOT_EXIST_DATA);
        }
        // 先删除角色和权限的关联关系
        var wrapper = new LambdaQueryWrapper<SysRolePermission>();
        wrapper.eq(SysRolePermission::getRoleId, rolePermissionDTO.getRoleId());
        rolePermissionMapper.delete(wrapper);
        // 添加关联关系
        if (rolePermissionDTO.getPermissionIds() != null && !rolePermissionDTO.getPermissionIds().isEmpty()) {
            rolePermissionDTO.getPermissionIds().forEach(m -> {
              var sysRolePermission= new SysRolePermission();
              sysRolePermission.setId(HandleUtils.UUID32());
              sysRolePermission.setCreator(userDTO.getUsername());
              sysRolePermission.setCreateDateTime(new Date());
              sysRolePermission.setPermissionId(m);
              sysRolePermission.setIsSoftDelete(false);
              sysRolePermission.setRoleId(rolePermissionDTO.getRoleId());
              int j=sysRolePermissionMapper.insert(sysRolePermission);
                if (j != 1) {
                    throw new RuntimeException("给角色分配权限失败");
                }
            });
        }
        // 先删除角色和功能的关联关系
        var wrapper1 = new LambdaQueryWrapper<SysOperationRole>();
        wrapper1.eq(SysOperationRole::getRoleId, rolePermissionDTO.getRoleId());
        sysOperationRoleMapper.delete(wrapper1);
        // 添加关联关系
        if (rolePermissionDTO.getOperationIds() != null && !rolePermissionDTO.getOperationIds().isEmpty()) {
            rolePermissionDTO.getOperationIds().forEach(m -> {
                var sysOperationRole= new SysOperationRole();
                sysOperationRole.setId(HandleUtils.UUID32());
                sysOperationRole.setCreator(userDTO.getUsername());
                sysOperationRole.setCreateDateTime(new Date());
                sysOperationRole.setOperationId(m);
                sysOperationRole.setIsSoftDelete(false);
                sysOperationRole.setRoleId(rolePermissionDTO.getRoleId());
                int j=sysOperationRoleMapper.insert(sysOperationRole);
                if (j != 1) {
                    throw new RuntimeException("给角色分配功能失败");
                }
            });
        }
        return RootResponse.success();
    }

    @Override
    public RootResponse treePermission() {
        var wrapper = new LambdaQueryWrapper<SysPermission>();
        List<PermissionTreeVO> permissionTreeVOList=new ArrayList<>();
        wrapper.eq(SysPermission::getIsSoftDelete, false);
        wrapper.orderByAsc(SysPermission::getSort);
        sysPermissionMapper.selectList(wrapper).forEach(p->{
            var permissionTreeVO=new PermissionTreeVO();
            BeanCopyUtils.copy(p,permissionTreeVO);
            permissionTreeVOList.add(permissionTreeVO);
        });
        if( permissionTreeVOList!=null&&permissionTreeVOList.size()!=0){
            MenuTree menuTree =new MenuTree(permissionTreeVOList);
            var  menuList=menuTree.builTree();
            menuList.forEach(m->{
                if(m.getPermissionTreeVOList()!=null&&m.getPermissionTreeVOList().size()!=0){
                    m.setButton(false);
                    getData(m.getPermissionTreeVOList());
                }
            });
            return RootResponse.success(menuList);
        }
        return RootResponse.success();
    }



    private RootResponse checkReName(String roleName) {
        var wrapper = new LambdaQueryWrapper<SysRole>();
        wrapper.eq(SysRole::getIsSoftDelete, false);
        wrapper.eq(SysRole::getRoleName, roleName);
        var role = baseMapper.selectCount(wrapper);
        if (role > 0) {
            return RootResponse.error();
        }
        return RootResponse.success();
    }
    private void getData( List<PermissionTreeVO> permissionTreeVOs ){

        permissionTreeVOs.forEach(m->{
            if(m.getPermissionTreeVOList()!=null&&m.getPermissionTreeVOList().size()!=0){
                m.setButton(false);
                getData(m.getPermissionTreeVOList());
            }else {
                m.setButton(true);
                var wrapper = new LambdaQueryWrapper<SysOperation>();
                wrapper.eq(SysOperation::getIsSoftDelete,false);
                wrapper.eq(SysOperation::getPageId,m.getId());
                m.setOperationsList( sysOperationMapper.selectList(wrapper));
            }
        });
    }
}
